home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
wtek0693.zip
/
OOPALLEY.ZIP
/
LIST.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-27
|
7KB
|
271 lines
#include "list.h"
#define THIS LinkedList
#define BASE SeqCltn
DEFINE_CLASS(LinkedList,SeqCltn);
LinkedList::LinkedList()
{
firstLink = lastLink = (Link*)nil;
count = 0;
}
bool LinkedList::operator==(const LinkedList& ll) const
{
if (count != ll.count) return NO;
else {
register Link* p = firstLink;
register Link* q = ll.firstLink;
while (p != (Link*)nil) {
if (!(p->isEqual(*q))) return NO;
p = p->nextLink();
q = q->nextLink();
}
}
return YES;
}
Object* LinkedList::add(const Object& ob)
{
assertArgClass(ob,class_Link,"add");
register Link* lnk = (Link*)&ob;
if (lnk->nextLink() != (Link*)nil) errDblLnk("add",*lnk);
if (count == 0) firstLink = lnk;
else lastLink->nextLink(lnk);
lastLink = lnk;
count++;
return (Object*)&ob;
}
Collection& LinkedList::addContentsTo(Collection& cltn) const
{
register Link* p = firstLink;
while (p != (Link*)nil) {
register Link* t = (Link*)p->copy();
t->nextLink((Link*)nil);
cltn.add(*t);
p = p->nextLink();
}
return cltn;
}
Object* LinkedList::addFirst(const Object& ob)
{
assertArgClass(ob,class_Link,"addFirst");
if (count == 0) return add(ob);
else {
register Link* lnk = (Link*)&ob;
if (lnk->nextLink() != (Link*)nil) errDblLnk("addFirst",*lnk);
lnk->nextLink(firstLink);
firstLink = lnk;
count++;
return (Object*)&ob;
}
}
Object* LinkedList::addLast(const Object& ob) { return add(ob); }
Object*& LinkedList::operator[](int i) const
{
if ((unsigned)i >= count) indexRangeErr();
if (i==0) return (Object*)firstLink;
else {
register Link* p = firstLink;
for (register int j=i-1; j>0; j--) p = p->nextLink();
return (Object*)p->next;
}
}
Object*& LinkedList::at(int i) const { return (*this)[i]; }
void LinkedList::atAllPut(const Object&) { shouldNotImplement("atAllPut"); }
void LinkedList::deepenShallowCopy()
{
BASE::deepenShallowCopy();
register Link* p = firstLink;
firstLink = lastLink = (Link*)nil;
count = 0;
while (p != (Link*)nil) {
add(*(p->deepCopy()));
p = p->nextLink();
}
}
#pragma warn -rvl // Turn of Warning: Function should return a value
Object* LinkedList::first() const
{
if (count==0)
{
errEmpty("first"); // aborts, return not executed
// return (Object*)NULL; // avoids Warning message
}else
return firstLink;
}
#pragma warn .rvl
unsigned LinkedList::hash() const
{
register unsigned h = count;
register Link* p = firstLink;
while (p != (Link*)nil) {
h^= p->hash();
p = p->nextLink();
}
return h;
}
int LinkedList::indexOf(const Object& ob) const
{
register int i = 0;
register Link* p = firstLink;
while (p != (Link*)nil) {
if (p->isEqual(ob)) return i;
p = p->nextLink();
i++;
}
return -1;
}
int LinkedList::indexOfSubCollection(const SeqCltn& /*cltn*/,
int /*start*/) const
{ shouldNotImplement("indexOfSubCollection"); return 0; }
bool LinkedList::isEmpty() const { return count==0; }
bool LinkedList::isEqual(const Object& a) const
{
return a.isSpecies(class_LinkedList) && *this==*(LinkedList*)&a;
}
const Class* LinkedList::species() const { return &class_LinkedList; }
#pragma warn -rvl // Turn of Warning: Function should return a value
Object* LinkedList::last() const
{
if (count==0)
{
errEmpty("last"); // aborts, return not executed
// return (Object*)NULL; // avoids Warning message
} else
return lastLink;
}
#pragma warn .rvl
Object* LinkedList::doNext(Iterator& pos) const
{
if (pos.ptr == 0) {
if (firstLink == nil) return 0;
else {
pos.ptr = firstLink;
pos.index = 1;
return firstLink;
}
}
else if ((Link*)pos.ptr == lastLink) return 0;
else {
pos.ptr = ((Link*)pos.ptr)->nextLink();
pos.index++;
return (Object*)pos.ptr;
}
}
unsigned LinkedList::occurrencesOf(const Object& ob) const
{
register unsigned n=0;
register Link* p = firstLink;
while (p != (Link*)nil) {
if (p->isEqual(ob)) n++;
p = p->nextLink();
}
return n;
}
void LinkedList::printOn(ostream& strm) const
{
strm << className() << "[\n";
register unsigned i = 0;
register Link* p = firstLink;
while (p != (Link*)nil) {
if (i>0) strm << "\n";
p->printOn(strm);
p = p->nextLink();
i++;
}
strm << "]\n";
}
Object* LinkedList::remove(const Object& ob)
{
assertArgClass(ob,class_Link,"remove");
if (count==0) errEmpty("remove");
register Link* lnk = (Link*)&ob;
if (lnk == firstLink) {
firstLink = lnk->nextLink();
if (lnk == lastLink) lastLink = (Link*)nil;
goto wrapup;
}
else {
register Link* p = firstLink;
while (p != (Link*)nil) {
if (lnk == p->nextLink()) {
p->nextLink(lnk->nextLink());
if (lnk == lastLink) lastLink = p;
goto wrapup;
}
p = p->nextLink();
}
errNotFound("remove",ob);
}
wrapup:
lnk->nextLink((Link*)nil);
count--;
return (Object*)&ob;
}
Object* LinkedList::removeFirst() { return remove(*firstLink); }
Object* LinkedList::removeLast() { return remove(*lastLink); }
void LinkedList::replaceFrom(int /*start*/, int /*stop*/, const SeqCltn& /*replacement*/, int /*startAt*/)
{
shouldNotImplement("replaceFrom");
}
void LinkedList::reSize(unsigned /*newSize*/) {}
unsigned LinkedList::size() const { return count; }
void LinkedList::errDblLnk(const char* fn, const Link& lnk) const
{
DTerror("", "");
cerr << "Attempt to add " << lnk.className()
<< " to two " << className() << "s: "
<< this << "->"
<< className() << "::" << fn
<< "((" << lnk.className() << "*)"
<< &lnk << ")"
<< "\n";
}
void LinkedList::errEmpty(const char* fn) const
{
DTerror("", "");
cerr << "Collection empty: "
<< this << "->"
<< className() << "::" << fn << "()"
<< "\n";
}
void LinkedList::errNotFound(const char* fn, const Object& ob) const
{
DTerror("", ""); // non fatal
cerr << "Object not found: "
<< this << "->"
<< className() << "::" << fn
<< "((" << ob.className() << "*)"
<< &ob << ")"
<< "\n";
}